using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace LateralProcesses
{
    /// <summary>
    /// This abstract class describes a generic form of Grouped Response Unit (CDU)
    /// </summary>
    public abstract class CDUClass:IComparable<CDUClass>
    {
        // 'protected' means these objects only viewable to derived classes of 'CDUClass'

        protected List<string> _gruId;
        protected List<double> _gruArea;

        //state and flux variables

        protected double lateralInflowFast;
        protected double lateralInflowSlow;
        protected double lateralInflowTotal;

        #region CDUClass Properties


        public string CDUID { get; set; }
        public string CDUIdDown { get; set; }
        public int RoutingOrder { get; set; }        
        public double Area { get; set; }
        public double Slope { get; set; }
        public double Aspect { get; set; }
        public double Elevation { get; set; }
        public bool Write { get; set; }// Returns true if GRU should be written to output and false if not
        public Dictionary<string, double> CduGlobalParameters { get; set; }
        public Dictionary<string, double> CduLocalParameters { get; set; }
        public Dictionary<string, double> FluxStateVars { get; set; }// Returns the CDU state variables for the current simulation time step        
        public double RunoffFast { get; set; }
        public double RunoffSlow { get; set; }
        public double RunoffTotal { get; set; }
        public double LateralInflowFast
        {
            //sum up all lateral inflows into a cdu
            //for one timestep (reset to 0.0 in Update method)
            set {  lateralInflowFast += value; }
        }
 
        public double LateralInflowSlow
        {
            //sum up all lateral inflows into a cdu
            //for one timestep (reset to 0.0 in Update method)
            set { lateralInflowSlow += value; }
        }
      

        #endregion

        #region CDUClass Methods

        /// <summary>
        /// Initializes CDU based on initial conditions provided. Assumes that
        /// CDU 
        /// </summary>
        /// <param name="InitialConditions"></param>
        public abstract void Initialize(Hashtable InitialConditions);

        /// <summary>
        /// Updates CDU state for given time step. 
        /// </summary>
        /// <param name="TimeStep">DateTime of simulation timestep</param>

        public abstract void Update(DateTime TimeStep, Dictionary<string, double> gruToCdu);


        /// <summary>
        /// Calcultes discharge from every CDU 
        /// </summary>


        #endregion
        //id, idDown, gruId, gruArea, area, Z, slope, aspect, parameters
        public CDUClass(string id, string idDown, List<string> gruId, List<double> gruArea, double area, double Z,
            double slope, double aspect, bool output, Dictionary<string, double> cduGlobalParameters, Dictionary<string, double> cduLocalParameters)
        {
            CDUID = id;
            CDUIdDown = idDown;
            _gruId = gruId;
            _gruArea = gruArea;
            Area = area;
            Elevation = Z;
            Slope = slope;
            Aspect = aspect;
            this.CduGlobalParameters = cduGlobalParameters;
            this.CduLocalParameters = cduLocalParameters;
            Write = output;

        }


        #region IComparable<CDUClass> Members

        int IComparable<CDUClass>.CompareTo(CDUClass other)
        {
            return this.RoutingOrder.CompareTo(other.RoutingOrder);
        }

        #endregion
    }
}
